package alp.starcode.nudtportal.framework.global;


import alp.starcode.common.exception.*;
import alp.starcode.common.result.Result;
import alp.starcode.nudtportal.framework.constant.CodeConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


/**
 * 全局异常捕获类
 *
 * @author lw
 * @date 2021年11月19日10:02:43
 */
@Slf4j
@RestControllerAdvice
@Component
public class GlobalExceptionHandle {

    /**
     * 设置异常信息
     *
     * @param result 返回结果
     * @param e      异常
     */
    private void setException(Result<Object> result, Exception e) {
        if (e instanceof BaseException) {
            if (((BaseException) e).isPrintStackTrace()) {
                log.error("全局异常", e);
            }
        } else {
            log.error("全局异常", e);
        }
        result.setError(e.getMessage());
    }

    /**
     * 所有异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Result<Object> exception(Exception e) {
        Result<Object> result = new Result<>(CodeConst.ERROR);
        setException(result, e);
        return result;
    }

    /**
     * 自定义异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = CustomException.class)
    public Result<Object> CustomException(CustomException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg() == null ? e.getMessage() : e.getMsg());
        setException(result, e);
        return result;
    }

    /**
     * 数据已存在异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = DataExistException.class)
    public Result<Object> DataExistException(DataExistException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        setException(result, e);
        return result;
    }

    /**
     * 数据不存在异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = DataNotExistException.class)
    public Result<Object> DataNotExistException(DataNotExistException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        setException(result, e);
        return result;
    }

    /**
     * 参数为空异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ParamsNullException.class)
    public Result<Object> ParamsNullException(ParamsNullException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        setException(result, e);
        return result;
    }

    /**
     * 外键异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ForeignKeyException.class)
    public Result<Object> ForeignKeyException(ForeignKeyException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        setException(result, e);
        return result;
    }

    /**
     * 主键异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = DuplicateKeyException.class)
    public Result<Object> DuplicateKeyException(DuplicateKeyException e) {
        Result<Object> result = new Result<>();
        result.setCode(CodeConst.DATA_IS_EXISTS.getCode());
        result.setMsg(CodeConst.DATA_IS_EXISTS.getMsg());
        setException(result, e);
        return result;
    }


    /**
     * 访问权限异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = AccessAuthorityException.class)
    public Result<Object> AccessAuthorityException(AccessAuthorityException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        setException(result, e);
        return result;
    }


    /**
     * 参数校验异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ValidatedException.class)
    public Result<Object> ValidatedException(ValidatedException e) {
        Result<Object> result = new Result<>();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        setException(result, e);
        return result;
    }

}
